package io.zpy.quartz;

import org.quartz.*;
import org.quartz.Trigger.TriggerState;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 计划任务管理
 *
 * @author DIY
 * 2018年5月16日  下午5:55:52
 */
@Service
public class QuartzManager {
    public final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private Scheduler scheduler;

    /**
     * 添加任务
     *
     * @param job
     */

    public void addJob(ScheduleJob job) throws Exception {
        // 创建jobDetail实例，绑定Job实现类
        // 指明job的名称，所在组的名称，以及绑定job类
        JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class)
                .withIdentity(job.getJobKey())
//											.withIdentity(job.getJobName(), job.getJobGroup()) //2选1
                .usingJobData(job.getDataMap()) //暂时先注掉
                .build();
        // 定义调度触发规则
        // 使用cornTrigger规则
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(job.getJobName(), job.getJobGroup())// 触发器key
                .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
                .startNow()
                .build();
        // 把作业和触发器注册到任务调度中
        scheduler.scheduleJob(jobDetail, trigger);
        // 判断调度器是否启动
        if (!scheduler.isStarted()) {
            scheduler.start();
        }
        log.info(String.format("定时任务:%s.%s-已添加到调度器!", job.getJobGroup(), job.getJobName()));

    }

    /**
     * 获取所有计划中的任务列表
     *
     * @return
     */
    public List<ScheduleJob> getAllJob() throws SchedulerException {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
        List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
        for (JobKey jobKey : jobKeys) {
            ScheduleJob job = ScheduleJob.getJobFromMap(scheduler.getJobDetail(jobKey).getJobDataMap());
            jobList.add(job);
        }
        return jobList;
    }

    /**
     * 所有正在运行的job
     *
     * @return
     */
    public List<ScheduleJob> getRunningJob() throws SchedulerException {
        List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
        List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
        for (JobExecutionContext executingJob : executingJobs) {
            ScheduleJob job = ScheduleJob.getJobFromMap(executingJob.getJobDetail().getJobDataMap());
            jobList.add(job);
        }
        return jobList;
    }

    /**
     * 暂停一个job
     *
     * @param job
     */
    public void pauseJob(ScheduleJob job) throws SchedulerException {
        if (scheduler.checkExists(job.getJobKey())) {
            scheduler.pauseJob(job.getJobKey());
            log.info(String.format("定时任务:%s.%s-已暂停!", job.getJobGroup(), job.getJobName()));
        } else {
            log.debug("Failed pause exist DynamicJob {}, because not fount JobKey [{}]", job, job.getJobKey());
        }
    }

    /**
     * 恢复一个job
     *
     * @param job
     */
    public void resumeJob(ScheduleJob job) throws SchedulerException {
        if (scheduler.checkExists(job.getJobKey())) {
            scheduler.resumeJob(job.getJobKey());
            log.info(String.format("定时任务:%s.%s-已重启!", job.getJobGroup(), job.getJobName()));
        } else {
            log.debug("Failed pause exist DynamicJob {}, because not fount JobKey [{}]", job, job.getJobKey());
        }
    }

    /**
     * 删除一个job
     *
     * @param job
     */
    public void deleteJob(ScheduleJob job) throws SchedulerException {
        if (scheduler.checkExists(job.getJobKey())) {
            scheduler.deleteJob(job.getJobKey());
            log.info(String.format("定时任务:%s.%s-已删除!", job.getJobGroup(), job.getJobName()));
        } else {
            log.debug("Failed pause exist DynamicJob {}, because not fount JobKey [{}]", job, job.getJobKey());
        }
    }

    /**
     * 立即执行job
     *
     * @param job
     */
    public void runAJobNow(ScheduleJob job) throws SchedulerException {
        if (scheduler.checkExists(job.getJobKey())) {
            scheduler.triggerJob(job.getJobKey());
            log.info(String.format("定时任务:%s.%s-立即启动!", job.getJobGroup(), job.getJobName()));
        } else {
            log.debug("Failed pause exist DynamicJob {}, because not fount JobKey [{}]", job, job.getJobKey());
        }

    }

    /**
     * 更新job时间表达式
     *
     * @param job
     * @param jobName
     * @param jobGroup
     * @return
     */
    public void updateJobCron(ScheduleJob job, String jobName, String jobGroup) throws SchedulerException {

        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());

        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()).withMisfireHandlingInstructionDoNothing();
        trigger = (CronTrigger) trigger.getTriggerBuilder().withIdentity(triggerKey)
                .usingJobData(job.getDataMap())
                .withSchedule(scheduleBuilder).build();
        scheduler.rescheduleJob(triggerKey, trigger);

        log.info(String.format("定时任务:%s.%s-更换新的执行时间[" + job.getCronExpression() + "]!", job.getJobGroup(), job.getJobName()));
    }

    public TriggerState jobIsRun(ScheduleJob job) {
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
        try {
            return scheduler.getTriggerState(triggerKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return null;
    }
}